package com.snts.synchronization.protocol.adapter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import nu.xom.Element;

import com.snts.synchronization.core.AuthResponse;
import com.snts.synchronization.core.BaseResponse;
import com.snts.synchronization.core.ErrorObject;
import com.snts.synchronization.core.ResponseStatus;
import com.snts.synchronization.protocol.ProtocolException;

public class AuthResponsePA extends BaseXMLProtocolAdapter<AuthResponse> {

	private AuthResponse authResponse;
	private ErrorObject errorObject;

	@Override
	protected AuthResponse popMessage() {
		authResponse.setErrorObject(errorObject);
		return authResponse;
	}

	@Override
	protected Element getMessageXOM(AuthResponse message)  {
		Element root = new Element("auth-response");
		Element status = new Element("status");
		status.appendChild(message.getStatus().name());
		root.appendChild(status);
		if(ResponseStatus.OK == message.getStatus()){
			Element sessionId = new Element("session-id");
			sessionId.appendChild(message.getSessionId());
			root.appendChild(sessionId);
		} else if(ResponseStatus.FAIL == message.getStatus()) {
			ErrorObject errorObject = message.getErrorObject();
			if(errorObject != null){
				Element error = getErrorXOM(errorObject);
				root.appendChild(error);
			}
		}
		return root;
	}

	public static void testStackTrace(int level) throws Exception{
		if(level >= 20){
			throw new Exception("Exception");
		}
		try {
			testStackTrace(level + 1);
		} catch(Exception ex){
			throw new Exception("Some Exception", ex);
		}
	}

	public static void main(String[] args) throws UnsupportedOperationException, IOException, ProtocolException{
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		AuthResponse authResponse = new AuthResponse();
		authResponse.setStatus(ResponseStatus.FAIL);
		try {
			testStackTrace(1);
		} catch (Exception ex){
			ErrorObject errorObject = new ErrorObject(3, "Session timed out", ex);
			authResponse.setErrorObject(errorObject);			
		}
//		authResponse.setSessionId("sess-id");
		AuthResponsePA authReponsePA = new AuthResponsePA();
		authReponsePA.serializeMessage(authResponse, baos);
		System.out.println(new String(baos.toByteArray(), Charset.forName("UTF-8")));
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		if("auth-response".equals(qName)){
			authResponse = new AuthResponse();
		} else if(ResponseStatus.FAIL == authResponse.getStatus()) {
			super.startElement(uri, localName, qName, attributes);
		}
	}

	@Override
	protected void doEndElement(String uri, String localName, String qName, String textValue) throws SAXException {
		if("status".equals(qName)){
			authResponse.setStatus(ResponseStatus.valueOf(textValue.trim().toUpperCase()));
		} else if("session-id".equals(qName)){
			authResponse.setSessionId(textValue.trim());
		} else if(ResponseStatus.FAIL == authResponse.getStatus()) {
			super.doEndElement(uri, localName, qName, textValue);
		}
	}

}
